home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
os2
/
cenvi2.arj
/
KEYPUSH.LIB
< prev
next >
Wrap
Text File
|
1993-12-16
|
12KB
|
358 lines
// KeyPush.lib - Windows routines to control, or mimic, the pushing of
// keys on the keyboard. This is one method of controlling
// windows applications. The functions in this library work
// by sending keyboard messages to the focus window as if
// the key messages were actually being sent by Windows.
//
// The functions in this library are:
//**KeyStroke([Holdkey1,HoldKey2,HoldKey3...]Character)
//**KeyStroke([Holdkey1,HoldKey2,HoldKey3...]VirtualKeyCode)
//**KeyStroke([Holdkey1,HoldKey2,HoldKey3...]KeyString)
// - Press and release a key or keys. If HoldKeys are given then will mimic
// that these keys are pressed before KeyCode or KeyString, and then
// will press and release KeyCode or KeyString, and then will release
// HoldKeys in reverse order.
// Examples: To press the 'S' key: KeyStroke('S');
// To type a sentence: KeyStroke("On top of Old Smokey!");
// To type Alt-F1: KeyStroke(VK_ALT,VK_F1);
// To simulate Ctl-Alt-R: KeyStroke(VK_CONTROL,VK_ALT,'R');
//**VKeyDown(KeyCode)
// - Press virtual key for Window.
// Key is not released.
// Example: KeyDown(VK_SHIFT)
//**VKeyUp(KeyCode)
// - Release key for focus Window.
// Example: KeyUp(VK_SHIFT)
//**SpeedKeys(AsciiString[,DelayBetweenCharacters])
// Speed keys sends only WM_CHAR messages to an application and is much
// faster thatn KeyStroke(), but should only be used for regular ascii
// strings passed to applications that don't need to for each specific
// keystroke. So, if KeyStroke() is too slow and you're entering a
// stretch of plain text, then use this function. If DelayBetweenCharacters
// is supplied then this many milliseconds will be paused between each char.
//
KeyPushWindow = 0; // If this is 0, then will send messages to whatever window
// has the focus. If this is not-zero then will send
// the FocuseWindow window handle.
/*** Virtual key values *************************************************/
#define VK_BUTTON1 0x01
#define VK_BUTTON2 0x02
#define VK_BUTTON3 0x03
#define VK_BREAK 0x04
#define VK_BACKSPACE 0x05
#define VK_TAB 0x06
#define VK_BACKTAB 0x07
#define VK_NEWLINE 0x08
#define VK_SHIFT 0x09
#define VK_CTRL 0x0A
#define VK_ALT 0x0B
#define VK_ALTGRAF 0x0C
#define VK_PAUSE 0x0D
#define VK_CAPSLOCK 0x0E
#define VK_ESC 0x0F
#define VK_SPACE 0x10
#define VK_PAGEUP 0x11
#define VK_PAGEDOWN 0x12
#define VK_END 0x13
#define VK_HOME 0x14
#define VK_LEFT 0x15
#define VK_UP 0x16
#define VK_RIGHT 0x17
#define VK_DOWN 0x18
#define VK_PRINTSCRN 0x19
#define VK_INSERT 0x1A
#define VK_DELETE 0x1B
#define VK_SCRLLOCK 0x1C
#define VK_NUMLOCK 0x1D
#define VK_ENTER 0x1E
#define VK_SYSRQ 0x1F
#define VK_F1 0x20
#define VK_F2 0x21
#define VK_F3 0x22
#define VK_F4 0x23
#define VK_F5 0x24
#define VK_F6 0x25
#define VK_F7 0x26
#define VK_F8 0x27
#define VK_F9 0x28
#define VK_F10 0x29
#define VK_F11 0x2A
#define VK_F12 0x2B
#define VK_F13 0x2C
#define VK_F14 0x2D
#define VK_F15 0x2E
#define VK_F16 0x2F
#define VK_F17 0x30
#define VK_F18 0x31
#define VK_F19 0x32
#define VK_F20 0x33
#define VK_F21 0x34
#define VK_F22 0x35
#define VK_F23 0x36
#define VK_F24 0x37
#define VK_ENDDRAG 0x38
#define VK_MENU VK_F10
KeyStroke(Key1,Key2,Key3/*etc...*/)
{
_argCount = va_arg();
// if more than one parameter, then hold down all but the last one
for ( k = 1; k < _argCount; k++ )
KeyDown(va_arg(k-1));
_key = va_arg(_argCount-1);
// Treat differently depending on whether Virtual Key Code, char, or string
if ( CMM_BYTE == DataType(_key) ) {
if ( 1 == DataDimension(_key) ) {
// send entire string one character at a time
for ( k = 0; _key[k]; k++ ) {
KeyDown(_key[k]);
KeyUp(_key[k]);
}
} else {
// send a single character out the port
KeyDown(_key);
KeyUp(_key);
}
} else {
// simply a virtual key code
KeyDown(_key);
KeyUp(_key);
}
// if more than one parameter, then reverse release all but the last one
for ( k = 1; k < _argCount; k++ )
KeyUp(va_arg(_argCount-k-1));
}
#define WM_CHAR 0x007a
#define WM_TRANSLATEACCEL 0x004b
/* WM_CHAR fs field bits */
#define KC_CHAR 0x0001
#define KC_VIRTUALKEY 0x0002
#define KC_SCANCODE 0x0004
#define KC_SHIFT 0x0008
#define KC_CTRL 0x0010
#define KC_ALT 0x0020
#define KC_KEYUP 0x0040
#define KC_PREVDOWN 0x0080
#define KC_LONEKEY 0x0100
#define KC_DEADKEY 0x0200
#define KC_COMPOSITE 0x0400
#define KC_INVALIDCOMP 0x0800
#define KC_TOGGLE 0x1000
#define KC_INVALIDCHAR 0x2000
#define KC_DBCSRSRVD1 0x4000
#define KC_DBCSRSRVD2 0x8000
LatestKeyDown = FALSE; // True on call to key down, false on KeyUp
KeyDown(Key)
{
// Save the current state of the 256-byte keyboard buffer
_keyTable = GetKeyboardTable();
LatestKeyDown = TRUE;
if ( CMM_BYTE == DataType(Key) ) {
// pushing just a character
fsflags = KC_CHAR;
usch = Key;
usvk = 0;
} else {
// pushing a virtual key
fsflags = KC_VIRTUALKEY;
usch = 0;
usvk = Key;
if ((_keyTable[Key] = (_keyTable[Key] | 0x80) ^ 1) & 0x01)
fsflags |= KC_TOGGLE;
SetKeyboardTable(_keyTable);
}
if ( _keyTable[VK_SHIFT] & 0x80 )
fsflags |= KC_SHIFT;
if ( _keyTable[VK_ALT] & 0x80 )
fsflags |= KC_ALT;
if ( _keyTable[VK_CTRL] & 0x80 )
fsflags |= KC_CTRL;
SendMessageAndAccelTable(fsflags | (1 << 16),usch | (usvk << 16));
}
KeyUp(Key)
{
// Save the current state of the 256-byte keyboard buffer
_keyTable = GetKeyboardTable();
// set some fsflags based on keys currently pressed
fsflags = KC_KEYUP /*| KC_PREVDOWN*/;
if ( CMM_BYTE == DataType(Key) ) {
// pushing just a character
fsflags |= KC_CHAR;
if ( (_keyTable[VK_CTRL] & 0x80) && isalpha(Key) )
// convert to control character
usch = toupper(Key) - 'A' + 1;
else
usch = Key;
usvk = 0;
} else {
// pushing a virtual key
fsflags |= KC_VIRTUALKEY;
usch = 0;
usvk = Key;
if ((_keyTable[Key] &= 0x7F) & 0x01);
fsflags |= KC_TOGGLE;
SetKeyboardTable(_keyTable);
}
if ( _keyTable[VK_SHIFT] & 0x80 )
fsflags |= KC_SHIFT;
if ( _keyTable[VK_ALT] & 0x80 )
fsflags |= KC_ALT;
if ( _keyTable[VK_CTRL] & 0x80 )
fsflags |= KC_CTRL;
if ( LatestKeyDown )
fsflags |= KC_LONEKEY;
LatestKeyDown = FALSE;
// send message to window that this key is being pressed
SendMessageAndAccelTable(fsflags | (1 << 16),usch | (usvk << 16));
}
SpeedKeys(AsciiString,DelayBetweenCharacters)
{
_skfocus = GetFocus();
_skdelay = ( 1 == va_arg() ) ? 0 : DelayBetweenCharacters ;
for ( c = AsciiString; c[0]; c++ ) {
Param1 = ((KC_CHAR | KC_LONEKEY)) | (1 << 16);
SendMessage(_skfocus,WM_CHAR,Param1,c[0]);
if ( _skdelay )
suspend( _skdelay );
}
}
/***********************************************************
*** PRIVATE UTILITIES USED BY THE ABOVE PUBLIC ROUTINES ***
***********************************************************/
#define HWND_DESKTOP 1
#define ORD_WIN32SETKEYBOARDSTATETABLE 921
GetKeyboardTable() // return 256 byte buffer for current keyboard state
{
_table[255] = '\0'; // initialize 256-byte key table
DynamicLink("PMWIN",ORD_WIN32SETKEYBOARDSTATETABLE,BIT32,CDECL,
HWND_DESKTOP,_table,FALSE);
return(_table);
}
SetKeyboardTable(_keyBuf) // set the 256 byte buffer for current keyboard state
{
DynamicLink("PMWIN",ORD_WIN32SETKEYBOARDSTATETABLE,BIT32,CDECL,
HWND_DESKTOP,_keyBuf,TRUE);
}
GetFocus() // return handle of Window with the focus
{
#define ORD_WIN32QUERYFOCUS 817
return( KeyPushWindow
? KeyPushWindow
: DynamicLink("PMWIN",ORD_WIN32QUERYFOCUS,BIT32,CDECL,HWND_DESKTOP) );
}
SendMessage(WindowHandle,MessageID,Param1,Param2)
{
#define ORD_WIN32SENDMSG 920
return PMDynamicLink("PMWIN",ORD_WIN32SENDMSG,BIT32,CDECL,
WindowHandle,MessageID,Param1,Param2);
}
/***********************/
/*** SHARED MEMORY ****/
// Initialize pointer to shared memory that will be given to windowed
// applications to receive their accelerator messages.
#define QMSG_SIZE 32
#define ORD_DOS32ALLOCSHAREDMEM 300
#define PAG_COMMIT 0x10
#define OBJ_GIVEABLE 0x200
#define PAG_READ 0x1
#define PAG_WRITE 0x2
assert( 0 == DynamicLink( "DOSCALLS", ORD_DOS32ALLOCSHAREDMEM, BIT32, CDECL,
_acceleratorQMsg, NULL, QMSG_SIZE,
PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE ) );
// zero all the bytes in this memory
for( _aqI = 0; _aqI < QMSG_SIZE; _aqI++ )
poke( _acceleratorQMsg + _aqI, 0 );
// Register function to free this memory when the current program exits
atexit("FreeAcceleratorMessageMemory");
FreeAcceleratorMessageMemory() // called at exit to free _acceleratorQMsg
{
#define ORD_DOS32FREEMEM 304
assert( 0 == DynamicLink( "DOSCALLS", ORD_DOS32FREEMEM, BIT32, CDECL,
_acceleratorQMsg ) );
}
/***********************************/
/*** SEND KEY MESSAGES TO WINDOW ***/
_currentWinHandle = 0; // save which window was previously given shaed memory
_currentProcessID;
_currentAccelTable;
SendMessageAndAccelTable(Param1,Param2)
// Send this message and send an accelerator table message
{
_focus = GetFocus();
// see that the current window has been given access to the shared
// memory table memory
if ( _focus != _currentWinHandle ) {
// This isn't the window we previously called. Must now get the
// Process ID of that window and give it access to the shared
// memory.
_currentWinHandle = _focus;
// Get Process ID of current focus window
undefine(_currentProcessID);
#define ORD_WIN32QUERYWINDOWPROCESS 838
assert( DynamicLink( "PMWIN", ORD_WIN32QUERYWINDOWPROCESS, BIT32, CDECL,
_focus, _currentProcessID, _PMAAT_dummy_tid ) );
// Give our shared memory to that process ID
#define ORD_DOS32GIVESHAREDMEM 303
assert( 0 == DynamicLink( "DOSCALLS", ORD_DOS32GIVESHAREDMEM, BIT32, CDECL,
_acceleratorQMsg, _currentProcessID,
PAG_READ | PAG_WRITE) );
}
// copy the message to the globally allocated and shared memory
// build blob message to give to accelerator table
poke( _acceleratorQMsg, _focus, UWORD32 );
poke( _acceleratorQMsg+4, WM_CHAR, UWORD32 );
poke( _acceleratorQMsg+8, Param1, UWORD32 );
poke( _acceleratorQMsg+12, Param2, UWORD32 );
// send message to window accelerator in case it wants to translate
SendMessage(_focus,WM_TRANSLATEACCEL,_acceleratorQMsg,0);
// send translated message to the window
SendMessage(peek(_acceleratorQMsg,UWORD32),peek(_acceleratorQMsg+4,UWORD32),
peek(_acceleratorQMsg+8,UWORD32),peek(_acceleratorQMsg+12,UWORD32));
}